﻿using Furion;
using Furion.DatabaseAccessor;
using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Diagnostics;
using ProjectManage.Core.Entity.SYS;
using System;
using System.Linq;

namespace ProjectManage.EntityFramework.Core.DbContexts
{
    [AppDbContext("ConnectionStrings:Default", DbProvider.SqlServer)]
    public class DefaultDbContext : AppDbContext<DefaultDbContext>
    {
        public DefaultDbContext(DbContextOptions<DefaultDbContext> options) : base(options)
        {
        }

        /// <summary>
        /// 重写保存之前事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected override void SavingChangesEvent(DbContextEventData eventData, InterceptionResult<int> result)
        {
            // 获取当前事件对应上下文
            var dbContext = eventData.Context;

            // 强制重新检查一边实体更改信息
            // dbContext.ChangeTracker.DetectChanges();

            // 获取所有更改，删除，新增的实体，但排除审计实体（避免死循环）
            var entities = dbContext.ChangeTracker.Entries()
                .Where(u => u.Entity.GetType() != typeof(SysAudit) && (u.State == EntityState.Modified || u.State == EntityState.Deleted || u.State == EntityState.Added))
                .ToList();

            // 获取所有已更改的实体
            foreach (var entity in entities)
            {
                // 获取实体类型
                var entityType = entity.Entity.GetType();

                // 获取所有实体有效属性，排除 [NotMapper] 属性
                var props = entity.OriginalValues.Properties;

                // 获取实体当前（现在）的值
                var currentValues = entity.CurrentValues;

                // 获取数据库中实体的值
                var databaseValues = entity.GetDatabaseValues();

                // 遍历所有属性
                foreach (var prop in props)
                {
                    // 获取属性名
                    var propName = prop.Name;

                    // 获取现在的实体值
                    var newValue = currentValues[propName];

                    object oldValue = null;
                    // 如果是新增数据，则 databaseValues 为空，所以需要判断一下
                    if (databaseValues != null)
                    {
                        oldValue = databaseValues[propName];
                    }

                    object userName ;
                    if(entity.State == EntityState.Added)
                    {
                        userName = currentValues["CreatedName"];
                    }
                    else if(entity.State == EntityState.Modified)
                    {
                        userName = databaseValues["ModifiedName"];
                    }
                    else
                    {
                        userName = "";
                    }

                    // 插入审计日志表，Audit 是你自定义的实体
                    dbContext.Set<SysAudit>().Add(new SysAudit
                    {
                        ID = Guid.NewGuid(),
                        Table = entityType.Name,    // 表名
                        Column = propName,  // 更新的列
                        NewValue = newValue?.ToString(),    // 新值
                        OldValue = oldValue?.ToString(),     // 旧值
                        CreatedTime = DateTime.Now, // 操作时间
                        UserId = userName?.ToString(),     // 操作人
                        Operate = entity.State.ToString()  // 操作方式：新增、更新、删除
                    });
                }
            }
        }
    }
}